/*******************************************************************************
* Copyright (c) 2011 Gerd Wuetherich (gerd@gerd-wuetherich.de).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Gerd Wuetherich (gerd@gerd-wuetherich.de) - initial API and implementation
******************************************************************************/
package org.bundlemaker.core.jdt.internal.parser;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
import org.bundlemaker.core.jtype.IModifiableType;
import org.bundlemaker.core.jtype.IParsableTypeResource;
import org.bundlemaker.core.jtype.JavaTypeUtils;
import org.bundlemaker.core.jtype.ReferenceAttributes;
import org.bundlemaker.core.jtype.ReferenceType;
import org.bundlemaker.core.jtype.TypeEnum;
import org.bundlemaker.core.spi.parser.IParsableResource;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
import org.eclipse.jdt.core.dom.ArrayCreation;
import org.eclipse.jdt.core.dom.CastExpression;
import org.eclipse.jdt.core.dom.CatchClause;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ConstructorInvocation;
import org.eclipse.jdt.core.dom.EnumDeclaration;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.IAnnotationBinding;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.IPackageBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.InstanceofExpression;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.Message;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
import org.eclipse.jdt.core.dom.ThisExpression;
import org.eclipse.jdt.core.dom.ThrowStatement;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.TypeLiteral;
import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
/**
* <p>
* </p>
*
* @author Gerd Wüerich (gerd@gerd-wuetherich.de)
*/
public class JdtAstVisitor extends ASTVisitor {
/** - */
private IParsableResource _javaSourceResource;
/** - */
private Stack<IModifiableType> _currentTypes;
/** - */
private Stack<String> _realTypes;
/** - */
private Stack<ITypeBinding> _typeBindings;
/** */
private Message[] _messages = new Message[0];
/** */
private IProblem[] _problems = new IProblem[0];
/**
* <p>
* Creates a new instance of type {@link JdtAstVisitor}.
* </p>
*
* @param javaSourceResource
* @param mapTypeInfo
*/
public JdtAstVisitor(IParsableResource javaSourceResource) {
Assert.isNotNull(javaSourceResource);
_javaSourceResource = javaSourceResource;
_typeBindings = new Stack<ITypeBinding>();
_currentTypes = new Stack<IModifiableType>();
_realTypes = new Stack<String>();
}
/**
* <p>
* </p>
*
* @return
*/
public Message[] getMessages() {
return _messages;
}
/**
* <p>
* </p>
*
* @return
*/
public List<org.bundlemaker.core.parser.IProblem> getProblems() {
List<org.bundlemaker.core.parser.IProblem> result = new LinkedList<org.bundlemaker.core.parser.IProblem>();
for (IProblem iProblem : _problems) {
if (iProblem.isError()) {
result.add(new JdtProblemAdapter(_javaSourceResource, iProblem));
}
}
return result;
}
/**
* <p>
* </p>
*
* @return
*/
public boolean hasErrors() {
//
for (IProblem problem : _problems) {
if (problem.isError()) {
return true;
}
}
//
return false;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. CompilationUnit)
*/
@Override
public boolean visit(CompilationUnit node) {
// get messages/problems
_messages = node.getMessages();
_problems = node.getProblems();
// visit the child nodes
return !hasErrors();
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. ImportDeclaration )
*/
@Override
public boolean visit(ImportDeclaration node) {
if (node.isOnDemand()) {
return false;
}
// binding exists
if (node.resolveBinding() != null && !node.resolveBinding().isRecovered()) {
// get the binding
IBinding binding = node.resolveBinding();
// add referenced package
if (binding instanceof IPackageBinding) {
/* Reference packageReference = */
_javaSourceResource.adaptAs(IParsableTypeResource.class).recordReference(((IPackageBinding) binding).getName(), new ReferenceAttributes(
ReferenceType.PACKAGE_REFERENCE, false, false, false, true, false, true, false));
}
// add referenced type
else if (binding instanceof ITypeBinding) {
resolveTypeBinding((ITypeBinding) binding, false, false, false);
}
// add referenced type
else if (binding instanceof IVariableBinding) {
IVariableBinding variableBinding = (IVariableBinding) binding;
ITypeBinding typeBinding = variableBinding.getDeclaringClass();
resolveTypeBinding(typeBinding, false, false, false);
}
}
// no binding exists
else {
if (!node.isOnDemand() && !node.isStatic()) {
addReferencedType(node.getName().getFullyQualifiedName(), false, false, false);
} else if (node.isOnDemand() && !node.isStatic()) {
addReferencedType(node.getName().getFullyQualifiedName(), false, false, false);
} else if (!node.isOnDemand() && node.isStatic()) {
Name importElementName = node.getName();
String fullQualifiedName = importElementName.getFullyQualifiedName().substring(0,
importElementName.getFullyQualifiedName().lastIndexOf('.'));
addReferencedType(fullQualifiedName, false, false, false);
}
}
// don't visit children
return false;
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. TypeDeclaration)
*/
@SuppressWarnings("unchecked")
@Override
public boolean visit(TypeDeclaration node) {
// add the type name
ITypeBinding typeBinding = node.resolveBinding();
TypeEnum typeEnum = null;
boolean abstractType = Modifier.isAbstract(node.getModifiers());
if (typeBinding.isInterface()) {
typeEnum = TypeEnum.INTERFACE;
abstractType = true;
} else if (typeBinding.isClass()) {
typeEnum = TypeEnum.CLASS;
} else {
// TODO
throw new RuntimeException("HAE " + node);
}
//
String binaryName = node.resolveBinding().getBinaryName();
// //
// IModifiableType realType =
// _javaSourceResource.getOrCreateType(binaryName,
// typeEnum);
IModifiableType currentType = null;
if (JavaTypeUtils.isLocalOrAnonymousTypeName(binaryName)) {
//
String outerType = JavaTypeUtils.getEnclosingNonLocalAndNonAnonymousTypeName(binaryName);
//
currentType = _javaSourceResource.adaptAs(IParsableTypeResource.class).getType(outerType);
} else {
//
currentType = _javaSourceResource.adaptAs(IParsableTypeResource.class).getOrCreateType(binaryName, typeEnum, abstractType);
}
_realTypes.push(binaryName);
_currentTypes.push(currentType);
// declared type superclass type
resolveType(node.getSuperclassType(), true, false, false);
// declared type implemented interfaces types
List<Type> interfaces = node.superInterfaceTypes();
for (Type iface : interfaces) {
resolveType(iface, false, true, false);
}
//
IAnnotationBinding[] annotationBindings = node.resolveBinding().getAnnotations();
for (IAnnotationBinding annotationBinding : annotationBindings) {
resolveTypeBinding(annotationBinding.getAnnotationType(), false, false, true);
}
// visit the child nodes
return true;
}
@Override
public void endVisit(TypeDeclaration node) {
_currentTypes.pop();
_realTypes.pop();
}
@Override
public boolean visit(AnnotationTypeDeclaration node) {
// add the type name
IModifiableType type = _javaSourceResource.adaptAs(IParsableTypeResource.class).getOrCreateType(node.resolveBinding().getBinaryName(),
TypeEnum.ANNOTATION, true);
_currentTypes.push(type);
_realTypes.push(node.resolveBinding().getBinaryName());
return true;
}
@Override
public void endVisit(AnnotationTypeDeclaration node) {
_currentTypes.pop();
_realTypes.pop();
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. EnumDeclaration)
*/
@SuppressWarnings("unchecked")
@Override
public boolean visit(EnumDeclaration node) {
// add the type name
IModifiableType type = _javaSourceResource.adaptAs(IParsableTypeResource.class).getOrCreateType(node.resolveBinding().getBinaryName(), TypeEnum.ENUM, false);
_currentTypes.push(type);
_realTypes.push(node.resolveBinding().getBinaryName());
// add super interfaces
List<Type> superInterfaces = node.superInterfaceTypes();
for (Type superInterface : superInterfaces) {
resolveType(superInterface, false, false, false);
}
//
IAnnotationBinding[] annotationBindings = node.resolveBinding().getAnnotations();
for (IAnnotationBinding annotationBinding : annotationBindings) {
resolveTypeBinding(annotationBinding.getAnnotationType(), false, false, true);
}
// visit the child nodes
return true;
}
@Override
public void endVisit(EnumDeclaration node) {
_currentTypes.pop();
_realTypes.pop();
}
/**
* <p>
* </p>
*
* @param node
* @return
*/
@Override
public boolean visit(AnnotationTypeMemberDeclaration node) {
// resolve the member type
resolveType(node.getType(), false, false, false);
// visit the child nodes
return true;
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. MethodDeclaration)
*/
@SuppressWarnings("unchecked")
@Override
public boolean visit(MethodDeclaration node) {
// declared method return type
resolveType(node.getReturnType2(), false, false, false);
// declared method argument types
List<SingleVariableDeclaration> variableDeclarations = node.parameters();
for (SingleVariableDeclaration singleVariableDeclaration : variableDeclarations) {
resolveType(singleVariableDeclaration.getType(), false, false, false);
}
// declared method exception types
List<Name> exceptions = node.thrownExceptions();
for (Name name : exceptions) {
resolveTypeName(name, false, false, false);
}
// visit the child nodes
return true;
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. FieldDeclaration)
*/
@Override
public boolean visit(FieldDeclaration node) {
// declared field type
resolveType(node.getType(), false, false, false);
// visit the child nodes
return true;
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. VariableDeclarationStatement)
*/
@Override
public boolean visit(VariableDeclarationStatement node) {
// resolve type name
resolveType(node.getType(), false, false, false);
// visit the child nodes
return true;
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. CatchClause)
*/
@Override
public boolean visit(CatchClause node) {
// resolve exception type
resolveType(node.getException().getType(), false, false, false);
// visit the child nodes
return true;
}
/****************/
/** Expressions */
/****************/
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. MarkerAnnotation)
*/
@Override
public boolean visit(MarkerAnnotation node) {
// resolve type name
resolveTypeName(node.getTypeName(), false, false, false);
// visit the child nodes
return true;
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. NormalAnnotation)
*/
@Override
public boolean visit(NormalAnnotation node) {
// resolve type name
resolveTypeName(node.getTypeName(), false, false, false);
// visit the child nodes
return true;
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. SingleMemberAnnotation)
*/
@Override
public boolean visit(SingleMemberAnnotation node) {
// resolve type name
resolveTypeName(node.getTypeName(), false, false, false);
// visit the child nodes
return true;
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. ArrayCreation)
*/
@Override
public boolean visit(ArrayCreation node) {
// resolve type
resolveType(node.getType(), false, false, false);
// visit the child nodes
return true;
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. CastExpression)
*/
@Override
public boolean visit(CastExpression node) {
// resolve type
resolveType(node.getType(), false, false, false);
// visit the child nodes
return true;
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. ClassInstanceCreation)
*/
@Override
public boolean visit(ClassInstanceCreation node) {
// resolve binding
IMethodBinding methodBinding = node.resolveConstructorBinding();
if (methodBinding != null) {
// resolve type arguments
ITypeBinding[] typeArguments = methodBinding.getParameterTypes();
for (ITypeBinding typeBinding : typeArguments) {
resolveTypeBinding(typeBinding, false, false, false);
}
// resolve type
resolveType(node.getType(), false, false, false);
}
// visit the child nodes
return true;
}
@Override
public boolean visit(FieldAccess node) {
// resolve type
IVariableBinding variableBinding = node.resolveFieldBinding();
if (variableBinding != null) {
resolveTypeBinding(variableBinding.getType(), false, false, false);
}
// visit the child nodes
return true;
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. InstanceofExpression)
*/
@Override
public boolean visit(InstanceofExpression node) {
// resolve type
resolveType(node.getRightOperand(), false, false, false);
// visit the child nodes
return true;
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. MethodInvocation)
*/
@SuppressWarnings("unchecked")
@Override
public boolean visit(MethodInvocation node) {
// access to static methods
IMethodBinding methodBinding = node.resolveMethodBinding();
resolveMethodBinding(methodBinding);
// resolve the associated expression
resolveExpressionType(node.getExpression());
// resolve the type arguments
List<Expression> typeArguments = node.arguments();
for (Expression exp : typeArguments) {
resolveExpressionType(exp);
}
// visit the child nodes
return true;
}
@Override
public boolean visit(ConstructorInvocation node) {
IMethodBinding methodBinding = node.resolveConstructorBinding();
// resolve type arguments
ITypeBinding[] parameterTypes = methodBinding.getParameterTypes();
for (ITypeBinding typeBinding : parameterTypes) {
resolveTypeBinding(typeBinding, false, false, false);
}
// visit the child nodes
return true;
}
@Override
public boolean visit(SuperConstructorInvocation node) {
// TODO: Zusammenlegen mit ConstructorInvocation
IMethodBinding methodBinding = node.resolveConstructorBinding();
// resolve type arguments
ITypeBinding[] parameterTypes = methodBinding.getParameterTypes();
for (ITypeBinding typeBinding : parameterTypes) {
resolveTypeBinding(typeBinding, false, false, false);
}
// List<Expression> typeArguments = node.arguments();
// for (Expression expression : typeArguments) {
// resolveTypeBinding(expression.resolveTypeBinding(), node
// .getStartPosition(), node.getLength());
// }
// visit the child nodes
return true;
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. QualifiedName)
*/
@Override
public boolean visit(QualifiedName node) {
// access to static fields
IBinding binding = node.resolveBinding();
if (binding != null) {
if (binding.getKind() == IBinding.VARIABLE) {
IVariableBinding variableBinding = (IVariableBinding) binding;
if (Flags.isStatic(variableBinding.getModifiers()) && variableBinding.getDeclaringClass() != null) {
resolveTypeBinding(variableBinding.getDeclaringClass(), false, false, false);
}
resolveTypeBinding(variableBinding.getType(), false, false, false);
}
}
return true;
}
@Override
public boolean visit(SimpleName node) {
IBinding binding = node.resolveBinding();
if (binding != null) {
if (binding.getKind() == IBinding.METHOD) {
resolveMethodBinding((IMethodBinding) binding);
}
}
// else if (binding.getKind() == IBinding.VARIABLE) {
//
// IVariableBinding variableBinding = (IVariableBinding) binding;
//
// ITypeBinding typeBinding = variableBinding.getType();
//
// resolveTypeBinding(typeBinding, node.getStartPosition(), node
// .getLength(), true, false);
// }
return super.visit(node);
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. ThisExpression)
*/
@Override
public boolean visit(ThisExpression node) {
// resolve type name
resolveTypeName(node.getQualifier(), false, false, false);
// visit the child nodes
return true;
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. TypeLiteral)
*/
@Override
public boolean visit(TypeLiteral node) {
// resolve type name
resolveType(node.getType(), false, false, false);
// visit the child nodes
return true;
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom. VariableDeclarationExpression)
*/
@Override
public boolean visit(VariableDeclarationExpression node) {
// resolve type name
resolveType(node.getType(), false, false, false);
// visit the child nodes
return true;
}
/***************/
/** Statements */
/***************/
@Override
public boolean visit(ThrowStatement node) {
if (node.getExpression() != null) {
resolveExpressionType(node.getExpression());
}
return true;
}
@Override
public boolean visit(ReturnStatement node) {
if (node.getExpression() != null) {
resolveExpressionType(node.getExpression());
}
return true;
}
/***************/
/** Internal resolve methods **/
/***************/
/**
* <p>
* Resolves the type name for the given type. If the type is <code>null</code> or a primitive type, <code>null</code>
* will be returned.
* </p>
*
* @param type
* the type to resolve
* @param isExtends
* TODO
* @param isImplements
* TODO
* @param resolveSuperTypes
*/
private void resolveType(Type type, boolean isExtends, boolean isImplements, boolean isClassAnnotation) {
// return null if type == null
if (type == null) {
return;
}
// resolve the type binding
resolveTypeBinding(type.resolveBinding(), isExtends, isImplements, isClassAnnotation);
}
/**
* @param typeName
* @return
*/
private void resolveTypeName(Name typeName, boolean isExtends, boolean isImplements, boolean isClassAnnotation) {
// return null if typeName == null
if (typeName == null) {
return;
}
// get the type binding
ITypeBinding typeBinding = typeName.resolveTypeBinding();
// return null if typeBinding == null
if (typeBinding == null) {
// TODO: Fehlermeldung!
return;
}
// return the qualified name
addReferencedType(typeBinding.getBinaryName(), isExtends, isImplements, isClassAnnotation);
}
/**
* <p>
* </p>
*
* @param typeBinding
* @param startPosition
* @param length
* @param resolveSuperTypes
*/
// private void resolveTypeBinding(ITypeBinding typeBinding,
// int startPosition, int length, boolean resolveSuperTypes) {
//
// resolveTypeBinding(typeBinding, startPosition, length,
// resolveSuperTypes, false);
// }
/**
* @param typeBinding
* @param isExtends
* TODO
* @param isImplements
* TODO
*/
private void resolveTypeBinding(ITypeBinding typeBinding, boolean isExtends, boolean isImplements,
boolean isClassAnnotation) {
// return null if type == null
if (typeBinding == null) {
return;
}
//
if (_typeBindings.contains(typeBinding)) {
return;
} else {
_typeBindings.push(typeBinding);
}
// handle array types
if (typeBinding.isArray()) {
resolveTypeBinding(typeBinding.getComponentType(), isExtends, isImplements, isClassAnnotation);
}
// handle parameterized types
else if (typeBinding.isParameterizedType()) {
// add the type
resolveTypeBinding(typeBinding.getErasure(), isExtends, isImplements, isClassAnnotation);
// add the type parameters
for (ITypeBinding iTypeBinding : typeBinding.getTypeArguments()) {
resolveTypeBinding(iTypeBinding, false, false, false);
}
}
// handle primitive types
else if (typeBinding.isPrimitive()) {
// do nothing...
}
// handle wildcard types
else if (typeBinding.isWildcardType()) {
// handle bound
resolveTypeBinding(typeBinding.getBound(), isExtends, isImplements, isClassAnnotation);
}
// handle type variable
else if (typeBinding.isTypeVariable()) {
ITypeBinding[] bindings = typeBinding.getTypeBounds();
for (ITypeBinding iTypeBinding : bindings) {
resolveTypeBinding(iTypeBinding, isExtends, isImplements, isClassAnnotation);
}
}
// handle capture
else if (typeBinding.isCapture()) {
// System.err.println("isCapture: " + typeBinding);
}
// handle others
else {
if (typeBinding.getJavaElement() == null) {
// System.err.println("*****");
// System.err.println(typeBinding);
// System.err.println("*****");
} else {
addReferencedType(((IType) typeBinding.getJavaElement()).getFullyQualifiedName('$'), isExtends, isImplements,
isClassAnnotation);
}
}
_typeBindings.pop();
}
/**
* <p>
* </p>
*
* @param methodBinding
*/
private void resolveMethodBinding(IMethodBinding methodBinding) {
// resolve declaring class if method is static
if (methodBinding != null) {
// static?
if (Flags.isStatic(methodBinding.getModifiers())) {
resolveTypeBinding(methodBinding.getDeclaringClass(), false, false, false);
}
// resolve type arguments
ITypeBinding[] typeArguments = methodBinding.getParameterTypes();
for (ITypeBinding typeBinding : typeArguments) {
resolveTypeBinding(typeBinding, false, false, false);
}
// resolve Exceptions
ITypeBinding[] exceptionTypes = methodBinding.getExceptionTypes();
for (ITypeBinding exceptionType : exceptionTypes) {
resolveTypeBinding(exceptionType, false, false, false);
}
// resolve return type
ITypeBinding returnType = methodBinding.getReturnType();
resolveTypeBinding(returnType, false, false, false);
//
if (methodBinding.isParameterizedMethod()) {
resolveMethodBinding(methodBinding.getMethodDeclaration());
}
//
else if (methodBinding.isGenericMethod()) {
ITypeBinding[] typeBindings = methodBinding.getTypeArguments();
for (ITypeBinding typeBinding : typeBindings) {
resolveTypeBinding(typeBinding, false, false, false);
}
}
}
}
/**
* <p>
* Adds the given referenced type to the set of referenced types.
* </p>
*
* @param referencedType
* the name of the referenced type
* @param startPosition
* @param length
* @param isExtends
* TODO
* @param isImplements
* TODO
*/
private void addReferencedType(String referencedType, boolean isExtends, boolean isImplements,
boolean isClassAnnotation) {
if (referencedType != null) {
if (!_currentTypes.isEmpty()) {
ReferenceAttributes referenceAttributes = null;
String currentTypeName = _currentTypes.peek().getFullyQualifiedName();
if (currentTypeName.equals(_realTypes.peek())) {
//
referenceAttributes = new ReferenceAttributes(ReferenceType.TYPE_REFERENCE, isExtends, isImplements,
isClassAnnotation, true, false, true, false);
} else {
//
referenceAttributes = new ReferenceAttributes(ReferenceType.TYPE_REFERENCE, false, false, false, true, false,
true, false);
}
//
_currentTypes.peek().recordReference(referencedType, referenceAttributes);
} else {
_javaSourceResource.adaptAs(IParsableTypeResource.class).recordReference(referencedType, new ReferenceAttributes(ReferenceType.TYPE_REFERENCE,
isExtends, isImplements, isClassAnnotation, true, false, true, false));
}
}
}
/**
* <p>
* </p>
*
* @param expression
*/
private void resolveExpressionType(Expression expression) {
if (expression != null) {
ITypeBinding typeBinding = expression.resolveTypeBinding();
if (typeBinding != null) {
resolveTypeBinding(typeBinding, false, false, false);
}
}
}
}